/*
 * Copyright (c) 2011, Space Applications Services
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of conditions
 * and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
 * and the following disclaimer in the documentation and/or other materials provided with the
 * distribution.
 *
 * None of the names of Space Applications Services, the GwtPiccolo project, or the names of its
 * contributors may be used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

var PShape, PEdge; 

(function () {

	PShape = PNode.extend({
		init: function (arg) {
		this._super(arg);
		this.shape = arg.shape || "CIRCLE";
		this.text = arg.text || "Hello";
		this.font = arg.font || "12px sans-serif";
	}, 

	paint: function (context) {
		if (this.fillStyle && !this.bounds.isEmpty()) 
		{
			if (this.shape == "CIRCLE")
			{
				context.fillStyle = this.fillStyle;
				context.beginPath();
				context.arc(this.bounds.x + this.bounds.width / 2, this.bounds.y + this.bounds.height / 2, this.bounds.width / 2, 0, Math.PI * 2, true);
				context.closePath();
				context.fill();
			}
			else if (this.shape == "TRIANGLE")
			{
				context.fillStyle = this.fillStyle;
				context.beginPath(); 
				var xpos = this.bounds.x + this.bounds.width / 2;
				context.moveTo(xpos, this.bounds.y);
				context.lineTo(xpos + this.bounds.width / 2, this.bounds.y + this.bounds.height);
				context.lineTo(xpos - this.bounds.width / 2, this.bounds.y + this.bounds.height);
				context.fill();
			}
			else if (this.shape == "ELLIPSE")
			{
				context.fillStyle = this.fillStyle;

				var kappa = .5522848;
				// control point offset horizontal
				var ox = (this.bounds.width / 2) * kappa;
				// control point offset vertical
				var oy = (this.bounds.height / 2) * kappa;
				var xe = this.bounds.x + this.bounds.width;      // x-end
				var ye = this.bounds.y + this.bounds.height;     // y-end
				var xm = this.bounds.x + this.bounds.width / 2;  // x-middle
				var ym = this.bounds.y + this.bounds.height / 2; // y-middle

				context.beginPath();
				context.moveTo(this.bounds.x, ym);
				context.bezierCurveTo(this.bounds.x, ym - oy, xm - ox, this.bounds.y, xm, this.bounds.y);
				context.bezierCurveTo(xm + ox, this.bounds.y, xe, ym - oy, xe, ym);
				context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
				context.bezierCurveTo(xm - ox, ye, this.bounds.x, ym + oy, this.bounds.x, ym);
				context.closePath();
				context.fill();

				context.fillStyle = "rgb(0,0,0)";
				context.textBaseline = "middle";
				context.textAlign = "start";
				context.font = this.font;
				var metrics = context.measureText(this.text);
				context.fillText(this.text, xm - metrics.width / 2, ym + 2);
			}
		}
	}});

	PEdge = PNode.extend({
		init: function(arg) 
		{
		this._super(arg);
		this.lineWidth = arg.lineWidth || 2;
		this.node1 = arg.node1 || new PNode(arg);
		this.node2 = arg.node2 || new PNode(arg);
		},

		paint: function (context)
		{
			context.lineWidth = this.lineWidth;
			context.beginPath();
			context.moveTo(this.node1.bounds.x + this.node1.bounds.width / 2, this.node1.bounds.y + this.node1.bounds.height / 2);
			context.lineTo(this.node2.bounds.x + (this.node2.bounds.width / 2), this.node2.bounds.y + (this.node2.bounds.height / 2));
			context.stroke();
		}
	});

})();
